package ClassAlgebra;

/**
 * Class for objects representing a so-called complex probability-expression. 
 * A complex probaiblity-expression is the sum or diffence between to probability-expression.
 *   P(a)-P(b)
 *   P(a)+P(b)
 * @author Martin Haulrich
 */
public class ComplexProbExpr implements ProbExpr {

    public final static int DIFFERENCE = 1;

    public final static int SUM = 2;

    public final ProbExpr pe1;

    public final ProbExpr pe2;

    public final int operation;

    final int hash;

    /**
     * @TODO Currently is is not the case that P(a)+P(b) = P(b)+P(a)
     */



    public ComplexProbExpr(ProbExpr pe1, ProbExpr pe2, int operation) {
        this.pe1 = pe1;
        this.pe2 = pe2;
        this.operation = operation;
        int h = 7;
        h = 71 * h + (this.pe1 != null ? this.pe1.hashCode() : 0);
        h = 71 * h + (this.pe2 != null ? this.pe2.hashCode() : 0);
        hash = 71 * h + this.operation;
    }


    @Override
    public String toString() {
        String op;
        switch (operation) {
            case DIFFERENCE:
                op = " - ";
                break;
            case SUM:
                op = " + ";
                break;

            default:
                op = " ";
        }

        return "(" + pe1 + op + pe2 + ")";
    }


    @Override
    public Object clone() throws CloneNotSupportedException {
        /**
         * @TODO The API dictates that by convention this method should be implemented useing super.clone(). Consider changing the code to do this.
         */
        return new ComplexProbExpr(pe1, pe2, operation);
    }


    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final ComplexProbExpr other = (ComplexProbExpr) obj;
        if (this.hash != other.hash) {
            return false;
        }

        if (this.pe1 != other.pe1 && (this.pe1 == null || !this.pe1.equals(other.pe1))) {
            return false;
        }
        if (this.pe2 != other.pe2 && (this.pe2 == null || !this.pe2.equals(other.pe2))) {
            return false;
        }
        if (this.operation != other.operation) {
            return false;
        }
        return true;
    }


    @Override
    public int hashCode() {
        
        return hash;
    }


//    @Override
//    public boolean equals(Object o) {
//
//        if (o instanceof ComplexProbExpr) {
//
//            ComplexProbExpr pe = (ComplexProbExpr) o;
//            return ((pe.operation == operation) && (pe.pe1.equals(pe1)) && (pe.pe2.equals(pe2)));
//        }
//        return false;
//    }
//
//
//    @Override
//    public int hashCode() {
//        return hash;
//    }
}
